/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package pkg1;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.sql.Time;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.Scanner;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;

/**
 *
 * @author Nick
 */
public class Main {

    /**
     * the home screen
     */
    private static JFrame layoutManager = new JFrame("Layout Manager");
    /**
     * the mother of all information
     */
    private static Context context;
    
    /**
     * runs the program
     * @param args 
     */
    public static void main(String[] args) {
        context = Context.getContext();
        setUpDoctorsAndNurses();
        createMenuBar();
        layoutManager.setLocationRelativeTo(null);
        Container contentPane = layoutManager.getContentPane();
        contentPane.setPreferredSize(new Dimension(300, 300));
        contentPane.setBackground(Color.CYAN);
        layoutManager.setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        layoutManager.pack();
        layoutManager.setVisible(true);
    }
    
    /**
     * creates the menubar of the homeScreen
     */
    private static void createMenuBar() {
        JMenuBar menuBar = new JMenuBar();
        JMenu menu = new JMenu("File");
        JMenuItem openER = new JMenuItem("OpenEmergencyRoom");
        openER.addActionListener(openERActionListener);
        JMenuItem templateList = new JMenuItem("New Floor From Template");
        templateList.setAccelerator(KeyStroke.getKeyStroke('F', InputEvent.CTRL_MASK));
        templateList.addActionListener(new OpenTemplateChooserAction());
        JMenuItem floorList = new JMenuItem("Open Floor");
        floorList.addActionListener(new OpenFloorChooserAction());
        floorList.setAccelerator(KeyStroke.getKeyStroke('O', InputEvent.CTRL_MASK));
        JMenuItem newFloorTemplate = new JMenuItem(new NewFloorTemplateAction("New Floor Template"));
        newFloorTemplate.setAccelerator(KeyStroke.getKeyStroke('N', InputEvent.CTRL_MASK));
        JMenuItem closeTemplate = new JMenuItem("Exit");
        closeTemplate.setAccelerator(KeyStroke.getKeyStroke('E', InputEvent.CTRL_MASK));
        closeTemplate.addActionListener(exitProgramListener);
        menu.add(newFloorTemplate);
        menu.add(templateList);
        menu.add(floorList);
        menu.add(openER);
        menu.add(closeTemplate);
        menuBar.add(menu);
        layoutManager.setJMenuBar(menuBar);
    }
   /**
     * Allows the user to create a new floor template
     */
   private static class NewFloorTemplateAction extends AbstractAction { 
        
        public NewFloorTemplateAction(String name) { 
            super(name); 
        }
        
        public void actionPerformed(ActionEvent e) {
            CreateNewFloorTemplate promptUserToNameTheFloor = new CreateNewFloorTemplate();
            promptUserToNameTheFloor.setVisible(true);
        }
   }
   
   /**
    * allows the user to terminate the program and is given the opportunity to save
    * opened floors and templates.
    */
   static ActionListener exitProgramListener = new AbstractAction() {
            public void actionPerformed(ActionEvent e) {
                Iterator<Window> windows = context.getWindows();
                while(windows.hasNext()) {
                    Window w = windows.next();
                    w.saveChangesToFloor();
                }
                System.exit(0);
            }
   };
   
   /**
    * allows the user to open the emergency room
    */
   static ActionListener openERActionListener = new AbstractAction() {
            public void actionPerformed(ActionEvent e) {
                if(context.getFloor("emergency room") == null) {
                    String fileName = "emergency room";
                    try {
                        Scanner scanner = new Scanner(new FileInputStream(fileName));
                        String name = scanner.nextLine();
                        int numberOfAnon = Integer.parseInt(scanner.nextLine());
                        scanner.nextLine();
                        ArrayList<Patient> patients = createPatients(scanner);
                        ArrayList<Bed> beds = createBeds(scanner);
                        ArrayList<Room> rooms = createRooms(scanner);
                        context.removeFloor(name);
                        FloorContext contextData = new FloorContext(name);
                        ArrayList<Bed> fcBeds = contextData.getBeds();
                        for(Bed bed : beds) {
                            fcBeds.add(bed);
                        }
                            ArrayList<Room> fcRooms = contextData.getRooms();
                        for(Room room : rooms) {
                            fcRooms.add(room);
                        }
                        ArrayList<Patient> fcPatients = contextData.getPatients();
                        context.addFloor(contextData);
                        HospitalFloor emergencyRoom = new HospitalFloor(contextData);
                        for(Patient patient : patients) {
                            Bed b = contextData.getBed(patient.getBedId());
                            contextData.admit(patient, context.getRandomDoctor(), context.getRandomNurse(), b);
                        }
                        contextData.setNumberOfAnnonymousPatients(numberOfAnon);
                        contextData.setChanged(false);
                        emergencyRoom.setVisible(true);

                    } catch (FileNotFoundException ex) {
                        Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
            }
   };
   
   /**
    * Allows the User to use an already saved template for a new floor
    */
   private static class OpenTemplateChooserAction extends AbstractAction { 
        
        public void actionPerformed(ActionEvent e) {
            JFileChooser chooser = new JFileChooser();
            int returned = chooser.showOpenDialog(layoutManager);
            if(returned == JFileChooser.APPROVE_OPTION) {
                String fileName = chooser.getSelectedFile().getPath();
                if(fileName.endsWith(".ftd")) {
                try {
                    Scanner scanner = new Scanner(new FileInputStream(fileName));
                    String name = scanner.nextLine();
                    scanner.nextLine();
                    ArrayList<Bed> beds = createBeds(scanner);
                    ArrayList<Room> rooms = createRooms(scanner);
                    FloorTemplateData templateData = new FloorTemplateData(rooms, beds, name);
                    CreateNewFloor newFloor = new CreateNewFloor(templateData);
                    newFloor.setVisible(true);
                    
                } catch (FileNotFoundException ex) {
                    Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                }
                }
                else{
                    
                    JOptionPane.showMessageDialog(layoutManager, "please Choose a .ftd file");
                }
            }
        }
   }
   
   /**
    * allows the user to open an already saved floor
    */
   private static class OpenFloorChooserAction extends AbstractAction { 
        
        public void actionPerformed(ActionEvent e) {
            JFileChooser chooser = new JFileChooser();
            int returned = chooser.showOpenDialog(layoutManager);
            if(returned == JFileChooser.APPROVE_OPTION) {
                String fileName = chooser.getSelectedFile().getPath();
                if(fileName.endsWith(".fcd")) {
                try {
                    Scanner scanner = new Scanner(new FileInputStream(fileName));
                    String name = scanner.nextLine();
                    if(context.getFloor(name) == null) {
                        int numberOfAnon = Integer.parseInt(scanner.nextLine());
                        scanner.nextLine();
                        ArrayList<Patient> patients = createPatients(scanner);
                        ArrayList<Bed> beds = createBeds(scanner);
                        ArrayList<Room> rooms = createRooms(scanner);
                        context.removeFloor(name);
                        FloorContext contextData = new FloorContext(name);
                        ArrayList<Bed> fcBeds = contextData.getBeds();
                        for(Bed bed : beds) {
                            fcBeds.add(bed);
                        }
                            ArrayList<Room> fcRooms = contextData.getRooms();
                        for(Room room : rooms) {
                            fcRooms.add(room);
                        }
                        ArrayList<Patient> fcPatients = contextData.getPatients();
                        FloorTemplate template = new FloorTemplate(contextData.getId(), contextData);
                        context.addFloor(contextData);
                        for(Patient patient : patients) {
                            Bed b = contextData.getBed(patient.getBedId());
                            contextData.admit(patient, context.getRandomDoctor(), context.getRandomNurse(), b);
                        }
                        contextData.setNumberOfAnnonymousPatients(numberOfAnon);
                        contextData.setChanged(false);
                        template.setVisible(true);
                    }
                    
                } catch (FileNotFoundException ex) {
                    Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                }
                }
                else{
                    
                    JOptionPane.showMessageDialog(layoutManager, "please Choose a .fcd file");
                }
            }
        }
   }
   
   /**
    * reconstructs beds based on saved information
    * @param scanner
    * @return 
    */
   private static ArrayList<Bed> createBeds(Scanner scanner) {
       ArrayList<Bed> beds = new ArrayList<Bed>();
       while(scanner.hasNextLine()) {
            boolean available = true;
            boolean cleaned = true;
            boolean specialCare = true;
            boolean visible = true;
            boolean normalBedInSpecialCare = true;
            int id = 0;
            String nextLine = scanner.nextLine();
            if(nextLine.equals("Rooms")) {
                return beds;
            }
            String[] splitLine = nextLine.split(",");
            for(String fragment : splitLine) {
                String[] splitFragment = fragment.split(":");
                if(splitFragment[0].equals("Available")) {
                    if(splitFragment[1].equals("true")) {
                        available = true;
                    }
                    else {
                        available = false;
                    }
                }

                if(splitFragment[0].equals("Cleaned")) {
                    if(splitFragment[1].equals("true")) {
                        cleaned = true;
                    }
                    else {
                        cleaned = false;
                    }
                }

                if(splitFragment[0].equals("SpecialCare")) {
                    if(splitFragment[1].equals("true")) {
                        specialCare = true;
                    }
                    else {
                        specialCare = false;
                    }
                }

                if(splitFragment[0].equals("normalBedInSpecialCare")) {
                    if(splitFragment[1].equals("true")) {
                        normalBedInSpecialCare = true;
                    }
                    else {
                        normalBedInSpecialCare = false;
                    }
                }
                
                if(splitFragment[0].equals("visible")) {
                    if(splitFragment[1].equals("true")) {
                        visible = true;
                    }
                    else {
                        visible = false;
                    }
                }

                if(splitFragment[0].equals("id")) {
                    id = Integer.parseInt(splitFragment[1]);
                }
            }
            Bed b = new Bed(available,cleaned,specialCare,normalBedInSpecialCare,id);
            if(!visible && !normalBedInSpecialCare && !(id == 102)) {
                b.setVisible(false);
                b.setAvailable(false);
            }
            if(!visible) {
                b.setVisible(false);
            }
            beds.add(b);
        }
       return beds;
   }
   
   /**
    * reconstructs rooms based on saved information
    * @param scanner
    * @return 
    */
   private static ArrayList<Room> createRooms(Scanner scanner) {
       ArrayList<Room> rooms = new ArrayList<Room>();
       while(scanner.hasNextLine()) {
            boolean inLayoutMode = true;
            boolean enabled = true;
            int id = 0;
            String nextLine = scanner.nextLine();
            String[] splitLine = nextLine.split(",");
            for(String fragment : splitLine) {
                String[] splitFragment = fragment.split(":");
                if(splitFragment[0].equals("InLayoutMode")) {
                    if(splitFragment[1].equals("true")) {
                        inLayoutMode = true;
                    }
                    else {
                        inLayoutMode = false;
                    }
                }

                if(splitFragment[0].equals("id")) {
                    id = Integer.parseInt(splitFragment[1]);
                }
                
                if(splitFragment[0].equals("Enabled")) {
                    if(splitFragment[1].equals("true")) {
                        enabled = true;
                    }
                    else {
                        enabled = false;
                    }
                }
            }
            Room r = new Room(id, inLayoutMode);
            if(!enabled) {  
                r.setDisabled();
            }
            rooms.add(r);
        }
       return rooms;
   }
   
   /**
    * reconstructs patients based on saved information
    * @param scanner
    * @return 
    */
   private static ArrayList<Patient> createPatients(Scanner scanner) {
       ArrayList<Patient> patients = new ArrayList<Patient>();
       while(scanner.hasNextLine()) {
            boolean isCritical = true;
            Date dateOfAdmissions = new Date();
            Date dateOfBirth = new Date();
            String gender = "";
            String name = "";
            int bedId = 0;
            int id = 0;
            String nextLine = scanner.nextLine();
            if(nextLine.equals("Beds")) {
                return patients;
            }
            String[] splitLine = nextLine.split(",");
            for(String fragment : splitLine) {
                String[] splitFragment = fragment.split(":");
                
                if(splitFragment[0].equals("IsCritical")) {
                    if(splitFragment[1].equals("true")) {
                        isCritical = true;
                    }
                    else {
                        isCritical = false;
                    }
                }
                
                if(splitFragment[0].equals("DateOfAdmissions")) {
                    dateOfAdmissions = convertStringToDate(splitFragment[1]);
                }
                
                if(splitFragment[0].equals("DateOfBirth")) {
                    dateOfBirth = convertStringToDate(splitFragment[1]);
                }

                if(splitFragment[0].equals("Id")) {
                    id = Integer.parseInt(splitFragment[1]);
                }
                
                if(splitFragment[0].equals("Name")) {
                    name = splitFragment[1];
                }
                
                if(splitFragment[0].equals("Gender")) {
                    gender = splitFragment[1];
                }
                
                if(splitFragment[0].equals("BedId")) {
                    bedId = Integer.parseInt(splitFragment[1]);
                }
            }
            Patient p = new Patient(name, isCritical, dateOfAdmissions, gender, dateOfBirth, id, bedId);
            patients.add(p);
        }
       return patients;
   }
   
   /**
    * helper method to convert saved strings to dates
    * @param date
    * @return 
    */
    private static Date convertStringToDate(String date) {
        int month = Integer.parseInt(date.substring(0, 2)) - 1;
        int day = Integer.parseInt(date.substring(2,4));
        int year = Integer.parseInt(date.substring(4,8)) - 1900;
        return new Date(year, month, day);
    }
   
    /**
     * helper method to construct a new emergency room with data
     */
   private static void setUpDoctorsAndNurses() {
        Doctor phil = new Doctor("Phil", 1);
        Doctor berney = new Doctor("Berney", 2);
        Doctor linda = new Doctor("Linda", 3);
        context.getDoctors().add(phil);
        context.getDoctors().add(berney);
        context.getDoctors().add(linda);
        Nurse cathy = new Nurse("Cathy", 1);
        Nurse ben = new Nurse("Ben", 2);
        Nurse pam = new Nurse("Pam", 3);
        context.getNurses().add(cathy);
        context.getNurses().add(ben);
        context.getNurses().add(pam);
   }
   
   /**
    * helper method to construct a new emergency room
    * if current room gets corrupted (mainly used for testing purposes)
    */
    public static void createEmergencyRoom() {
            FloorContext emergencyRoom = new FloorContext("emergency room");
            context.addFloor(emergencyRoom);
            HospitalFloor frame = new HospitalFloor(emergencyRoom);
            admitPatientsToEmergencyRoom(emergencyRoom);
            frame.save(emergencyRoom);
    }
    
    /**
     * helper method for constructing a new emergencyRoom
     * @param emergencyRoom 
     */
    private static void admitPatientsToEmergencyRoom(FloorContext emergencyRoom) {
            Patient nick = new Patient("Nick", false, new Date(), "male", new Date(0, 10, 5), 1, 0);
            Patient charlie = new Patient("Charlie", false, new Date(), "male", new Date(0, 10, 5), 2, 0);
            Patient rose = new Patient("Rose", false, new Date(), "female", new Date(0, 10, 5), 3, 0);
            Patient fred = new Patient("Fred", false, new Date(), "male", new Date(0, 10, 5), 5, 0);
            Patient bob = new Patient("Bob", false, new Date(), "male", new Date(0, 10, 5), 6, 0);
            Patient ann = new Patient("Ann", false, new Date(), "female", new Date(0, 10, 5), 7, 0);
            Patient kyle = new Patient("Kyle", false, new Date(), "male", new Date(0, 10, 5), 8, 0);
            Patient lin = new Patient("Lin", false, new Date(), "female", new Date(0, 10, 5), 9, 0);

            Patient bart = new Patient("Bart", false, new Date(), "male", new Date(0, 10, 5), 10, 0);
            Patient bert = new Patient("Bert", false, new Date(), "male", new Date(0, 10, 5), 11, 0);
            Patient nora = new Patient("Nora", false, new Date(), "female", new Date(0, 10, 5), 12, 0);
            Patient juan = new Patient("Juan", false, new Date(), "male", new Date(0, 10, 5), 13, 0);
            Patient maggie = new Patient("Maggie", false, new Date(), "female", new Date(0, 10, 5), 14, 0);
            Patient peter = new Patient("Peter", false, new Date(), "male", new Date(0, 10, 5), 15, 0);
            Patient nancy = new Patient("Nancy", false, new Date(), "female", new Date(0, 10, 5), 16, 0);
            emergencyRoom.admit(bart, context.getRandomDoctor(), context.getRandomNurse(), emergencyRoom.getBeds().get(0));
            emergencyRoom.admit(bert, context.getRandomDoctor(), context.getRandomNurse(), emergencyRoom.getBeds().get(1));
            emergencyRoom.admit(nora, context.getRandomDoctor(), context.getRandomNurse(), emergencyRoom.getBeds().get(2));
            emergencyRoom.admit(kyle, context.getRandomDoctor(), context.getRandomNurse(), emergencyRoom.getBeds().get(3));
            emergencyRoom.admit(bob, context.getRandomDoctor(), context.getRandomNurse(), emergencyRoom.getBeds().get(4));
            emergencyRoom.admit(fred, context.getRandomDoctor(), context.getRandomNurse(), emergencyRoom.getBeds().get(5));
            emergencyRoom.admit(maggie, context.getRandomDoctor(), context.getRandomNurse(), emergencyRoom.getBeds().get(6));
            emergencyRoom.admit(juan, context.getRandomDoctor(), context.getRandomNurse(), emergencyRoom.getBeds().get(7));
            emergencyRoom.admit(charlie, context.getRandomDoctor(), context.getRandomNurse(), emergencyRoom.getBeds().get(8));
            emergencyRoom.admit(ann, context.getRandomDoctor(), context.getRandomNurse(), emergencyRoom.getBeds().get(10));
            emergencyRoom.admit(lin, context.getRandomDoctor(), context.getRandomNurse(), emergencyRoom.getBeds().get(11));
            emergencyRoom.admit(peter, context.getRandomDoctor(), context.getRandomNurse(), emergencyRoom.getBeds().get(12));
            emergencyRoom.admit(nancy, context.getRandomDoctor(), context.getRandomNurse(), emergencyRoom.getBeds().get(13));
            emergencyRoom.admit(nick, context.getRandomDoctor(), context.getRandomNurse(), emergencyRoom.getBeds().get(14));
            emergencyRoom.admit(rose, context.getRandomDoctor(), context.getRandomNurse(), emergencyRoom.getBeds().get(15));
        }
}
